package com.dj.persistence.dao;

import com.dj.persistence.entity.Account;

import java.util.List;
import java.math.BigDecimal;

/**
 * User: Jacob
 * Date: Jul 19, 2008
 * Time: 5:11:22 PM
 */
public interface AccountDao {

    /**
     * Create an account in the persistance storage and return the newly created account.
     *
     * @param account the new account to be created.
     * @return the newly created account
     */
    public Account createAccount(Account account);

    /**
     * Disables the account so that no transactions can be performed.
     *
     * @param accountId the account id
     * @return true is operation is successfull, else false.
     */
    public boolean disableAccount(Long accountId);

    /**
     * Enables the account so that  transactions can be performed.
     *
     * @param accountId the account id
     * @return true is operation is successfull, else false.
     */
    public boolean enableAccount(Long accountId);


    /**
     * Get the account details for this account id.
     * If no matching account is found null will be returned.
     *
     * @param id the account.
     * @return the account matching the id
     */
    public Account getAccount(Long id);

    /**
     * Returns one or more accounts matching this account number.
     * If the provided accountNo is partial, none or more than one account
     * details can be probably matched.
     *
     * @param accountNo Complete or partial account no.
     * @return a list of account details matching this account no.
     */
    public List<Account> getAccount(String accountNo);

    /**
     * Use this method to fetch accounts basedon multiple criteria.
     * Fetch all the accounts matching the account provided.
     *
     * @param account - the criterion object based on which accounts are fetched
     * @return list of account details matching provided crietria.
     */
    public List<Account> getAccountsMatching(Account account);

    /**
     * Fetch all the accounts having a balance equal or more than a spsecific amount.
     *
     * @param amount the amount passed
     * @return all the accounts having a balance equal or more than this amount.
     */
    public List<Account> getAccountsHavingBalanceEqualOrMoreThan(BigDecimal amount);

    /**
     * Debit the provided amount from the account
     *
     * @param accountId account id from which the debit operation has to be performed
     * @param amount    amount to debit
     * @return true is account has sufficient balance and other prerequisites to debit this amount, else false.
     */
    public boolean debit(Long accountId, BigDecimal amount);

    /**
     * Credit amount to the provided account.
     *
     * @param accountId the acount id to which the amount to be credited
     * @param amount  the amount to be credited.
     * @return true if amount had been credited.
     */
    public boolean credit(Long accountId, BigDecimal amount);


    /**
     * Sets the balance of this account. This method should be ideally called after every transaction.
     *
     * @param accountId the account id
     * @param balance   the balance to set
     * @return the account having the latest balance
     */
    public Account setAccountBalance(Long accountId, BigDecimal balance);

}
